import hljs from "highlight.js";

/**
 * 处理md内容，将解析的md挂载到对应的容器中，并生成目录，挂载到目录容器中
 * @param container md容器
 * @param menu md目录容器
 * @param data 解析的md数据
 */
const processMd = (container: HTMLDivElement, menu: HTMLUListElement, data: string) => {
    container.innerHTML = data
    let flag = -1
    container.childNodes.forEach((item, index) => {
        // 删除原有的目录
        if (item.textContent == '目录') {
            flag = index + 1
            item.remove()
        }
        if (index == flag) {
            item.remove()
        }
    })

    container.querySelectorAll('a').forEach(a => {
        // 删除所有内部跳转的链接
        if (a.href.match(location.origin + '/#')) {
            a.remove();
        }
    })

    hljs.highlightAll() // 高亮所有代码

    container.querySelectorAll('code').forEach(code => {
        // 创建code类型标识
        const divElement = document.createElement('div')
        const classListElement = code.classList[0];
        if (classListElement != null) {
            divElement.innerText = classListElement.substring('language-'.length)
            divElement.className = 'code-type'
            code.appendChild(divElement)
        }
    })

    interface mi {
        name: string,
        children: [mi?],
        item: Element
    }

    let m: [mi?] = [] // 目录对象
    const pushTo = (list: [mi?], height: number, name: string, item: Element) => {
        // 根据标题的等级来创建层级菜单
        if (list.length == 0) {
            list.push({name, children: null, item})
            return
        }
        if (height != 1) {
            if (list[list.length - 1].children == null) {
                list[list.length - 1].children = []
            }
            pushTo(list[list.length - 1].children, height - 1, name, item)
        } else {
            list.push({name, children: null, item})
        }
    }

    // 根据标题生成目录对象
    const element = container.querySelectorAll("h1, h2, h3, h4, h5, h6")
    element.forEach((item) => {
        pushTo(m, Number.parseInt(item.nodeName.substring(1, 2)), item.textContent, item)
    })

    menu.innerHTML = null
    const toLiObj = (item: Element, name: string, height: number): HTMLLIElement => {
        const li = document.createElement("li")
        li.style.paddingLeft = (20 + height * 30) + 'px'
        li.textContent = name
        li.addEventListener("click", () => {
            // 点击目录后跳转到目标元素
            item.scrollIntoView()
            menu.style.display = 'none'
        })
        return li
    }
    const process = (list: mi[], height: number) => {
        // 根据目录对象生成目录
        list.forEach((item) => {
            menu.appendChild(toLiObj(item.item, item.name, height))
            if (item.children != null) {
                process(item.children, height + 1)
            }
        })
    }
    process(m, 0)

    m = null // 清除临时对象
}

export default processMd
